# -*- coding: utf-8 -*-

from enum import IntEnum
from hlm.base import Pack


class AluOpCode(IntEnum):
    # ALU type operations.
    NOP = 0
    ADD = 1
    SUB = 2
    MUL = 3
    DIV = 4

    # Memory operations.
    PUT = 20

    # Conditions.
    WAIT = 70

    # Halt.
    HALT = 100


class TranOpCode(IntEnum):
    LD = 0
    CLR = 1


class AllocOpCode(IntEnum):
    DQ = 0


class ExecOp(Pack):
    def __init__(self):
        self.alu: int = 0
        self.peer_id: int = 0
        self.len_limit: int = 0
        self.op_code: AluOpCode = AluOpCode.NOP

        self.dst_addr: bool = False
        self.dst_increase: int = 0
        self.dst_enable_offset: bool = False
        self.dst_peer_id: int = 0
        self.dst_stride: int = 0
        self.dst_sb: bool = False

        self.src_addr_0: int = 0
        self.src_wait_passin_0: bool = False
        self.src_wait_aluin_0: bool = False
        self.src_enable_offset_0: bool = False
        self.src_stride_0: int = 0
        self.src_limit_0: int = 0

        self.src_addr_1: int = 0
        self.src_wait_passin_1: bool = False
        self.src_wait_aluin_1: bool = False
        self.src_enable_offset_1: bool = False
        self.src_stride_1: int = 0
        self.src_limit_1: int = 0


class TranOp(Pack):
    def __init__(self):
        self.len_limit: int = 0
        self.op_code: TranOpCode = TranOpCode.LD

        # Peer-side
        self.dst_peer_id: int = 0
        self.dst_addr: int = 0
        self.dst_stride: int = 0
        self.dst_clear: bool = False
        self.dst_sb_addr: int = 0
        self.dst_ain_addr: int = 0

        # Memory-side
        self.src_addr: int = 0
        self.src_stride: int = 0


class AllocOp(Pack):
    def __init__(self):
        self.addr: int = 0
        self.data: complex = 0

        self.op_code: AllocOpCode = AllocOpCode.DQ